#include <cstddef>

template<class T>
class Vector;

template<class T, class Ref, class Ptr>
class __vector_iterator
{
private:
   typedef __vector_iterator<T, Ref, Ptr> Self;

public:
   __vector_iterator(T* index)
      :_index(index)
   {}

   __vector_iterator(const Self& other)
      :_index(other._index)
   {}

   Ref operator*()
   {
      return *_index;
   }

   Ptr operator->()
   {
      return &(operator*());
   }

   bool operator==(const Self& other)
   {
      return (_index == other._index);
   }

   bool operator!=(const Self& other) {
      return !(operator==(other));
   }

   Self& operator++()
   {
      ++_index;
      return *this;
   }

   Self& operator++(int)
   {
      Self tmpObj = *this;
      ++_index;
      return tmpObj;
   }

   Self& operator--()
   {
      --_index;
      return *this;
   }

   Self& operator--(int)
   {
      Self tmpObj = *this;
      --_index;
      return tmpObj;
   }

private:
   T* _index;
};

template<class T>
class Vector
{
public:
   typedef __vector_iterator<T, T&, T*> iterator;
   typedef __vector_iterator<T, const T&,const T*> const_iterator;

public:
   Vector()
      :_p(nullptr)
   {}

   Vector(size_t n, const T& val = T())
      :_p(nullptr)
   {
      _p = new T[n];
      for (int i = 0; i < n; ++i) {
	 _p[i] = val;
      }
      _sz = _capa = n;
   }

   T& operator[](int pos) 
   {
      return _p[pos];
   }

   size_t size()
   {
      return _sz;
   }

   virtual ~Vector()
   {
      delete[] _p;
   }

public:
   iterator begin()
   {
      return iterator(_p);
   }

   iterator end()
   {
      return iterator(_p + _sz);
   }

private:
   T *_p;
   size_t _sz;
   size_t _capa;
};
